package cn.qingyun.gis.modules.enterprise.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.qingyun.gis.exception.CommonException;
import cn.qingyun.gis.modules.enterprise.entity.Grid;
import cn.qingyun.gis.modules.enterprise.entity.Permissions;
import cn.qingyun.gis.modules.enterprise.mapper.GridMapper;
import cn.qingyun.gis.modules.enterprise.response.RegionResponse;
import cn.qingyun.gis.modules.enterprise.service.IGridService;
import cn.qingyun.gis.modules.enterprise.service.IPermissionsService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 区划数据表 服务实现类
 * </p>
 *
 * @author skb
 * @since 2024-03-29
 */
@Service
@Slf4j
public class GridServiceImpl extends ServiceImpl<GridMapper, Grid> implements IGridService {

    @Autowired
    private IPermissionsService iPermissionsService;

    /**
     * 获取用户权限下地区数据（如果有网格权限，也返回网格）
     *
     * @return List
     */
    @Override
    public List getRegionList() {
        long startTime = System.currentTimeMillis();
        List<Permissions> permissions = iPermissionsService.getPermissions();
        if (Objects.isNull(permissions)) {
            throw new CommonException("获取人员权限失败");
        }
        List<RegionResponse> allList = new ArrayList<>();
        List<Permissions> sortPermissions = permissions.stream().sorted(Comparator.comparingInt(item -> item.getAllParentCode().split(",").length)).collect(Collectors.toList());
        List<String> allCode = new ArrayList<>();
        for (Permissions datum : sortPermissions) {
            String[] areaCode = datum.getAllParentCode().split(",");
            String[] areaName = datum.getFullName().split("-");
            if (!Objects.equals(areaCode.length, areaName.length)) {
                throw new CommonException("解析接口-区域编码与名称映射出错！");
            }
            List<RegionResponse> list = new ArrayList<>();
            //如果是省级权限
            if (areaCode.length == 1) {
                QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().select(Grid::getCode, Grid::getName, Grid::getParentCode, Grid::getParentName).eq(Grid::getLevel, "1").or().eq(Grid::getLevel, "2").or().eq(Grid::getLevel, "3").orderByAsc(Grid::getLevel);
                List<Grid> gridList = this.list(queryWrapper);
                list = BeanUtil.copyToList(gridList, RegionResponse.class);
                allCode.add(datum.getAllParentCode());
            } else if (areaCode.length == 2) {//市级权限
                QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().select(Grid::getCode, Grid::getName, Grid::getParentCode, Grid::getParentName).eq(Grid::getParentCode, datum.getAreaCode()).or().eq(Grid::getCode, datum.getAreaCode());
                List<Grid> gridList = this.list(queryWrapper);
                QueryWrapper<Grid> sdWrapper = new QueryWrapper<>();
                sdWrapper.lambda().select(Grid::getCode, Grid::getName, Grid::getParentCode, Grid::getParentName).eq(Grid::getLevel, "1");
                Grid sd = this.getOne(sdWrapper);
                RegionResponse sdRegion = new RegionResponse();
                BeanUtils.copyProperties(sd, sdRegion);
                sdRegion.setClick(false);
                list = BeanUtil.copyToList(gridList, RegionResponse.class);
                list.add(sdRegion);
                allCode.add(datum.getAllParentCode());
            } else if (areaCode.length == 3) {
                for (int i = 0; i < areaCode.length; i++) {
                    RegionResponse region = new RegionResponse();
                    if (i == 0) {
                        region.setCode(areaCode[i]).setParentCode("0").setName(areaName[i]).setParentName("").setClick(false);
                    } else if (i == 1) {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(false);
                    } else {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(true);
                    }
                    list.add(region);
                }
                allCode.add(datum.getAllParentCode());
            } else if (areaCode.length == 4) {
                if (allCode.stream().anyMatch(item -> datum.getAllParentCode().startsWith(item))) {
                    continue;
                }
                for (int i = 0; i < areaCode.length; i++) {
                    RegionResponse region = new RegionResponse();
                    if (i == 0) {
                        region.setCode(areaCode[i]).setParentCode("0").setName(areaName[i]).setParentName("").setClick(false);
                    } else if (i == 1) {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(false);
                    } else {
                        region.setCode(areaCode[i]).setParentCode(areaCode[i - 1]).setName(areaName[i]).setParentName(areaName[i - 1]).setClick(true);
                    }
                    list.add(region);
                }
            }
            allList.addAll(list);
        }
        //TODO 有隐患，如何根据字段值进行去重
        List<RegionResponse> groupCollect = allList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(RegionResponse::getCode))), ArrayList::new));
        List<RegionResponse> collect = groupCollect.stream().filter(item -> !item.getName().contains("政企") && !item.getName().contains("校园") && !item.getName().contains("虚拟网格") && !item.getName().contains("商企网格")).collect(Collectors.toList());
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("code");//默认id，可以不设置
        config.setParentIdKey("parentCode");//父id
        config.setNameKey("name");//分类名称
        config.setChildrenKey("childNode");//孩子节点
        config.setWeightKey("code");//排序字段
        //3.转树
        List<Tree<String>> list = TreeUtil.build(collect, "0", config, ((object, treeNode) -> {
            treeNode.putExtra("code", object.getCode());
            treeNode.putExtra("parentCode", object.getParentCode());
            treeNode.putExtra("name", object.getName());
            treeNode.putExtra("parentName", object.getParentName());
            treeNode.putExtra("isClick", object.isClick());
        }));
        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;
        log.info("解析数据执行时间：{}毫秒", executionTime);
        return list;
    }

    /**
     * 获取网格数据
     *
     * @param code
     * @return
     */
    @Override
    public List<Grid> getGridList(String code) {
        QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(Grid::getCode, Grid::getName, Grid::getParentCode).eq(Grid::getParentCode, code);
        List<Grid> channelGridList = this.list(queryWrapper);
        List<Grid> list = channelGridList.stream().filter(item -> !item.getName().contains("政企") && !item.getName().contains("校园") && !item.getName().contains("虚拟网格") && !item.getName().contains("商企网格")).sorted(Comparator.comparing(Grid::getCode)).collect(Collectors.toList());
        return list;
    }

    @Override
    public List<Tree<String>> getTreeList() {
        long startTime = System.currentTimeMillis();
        QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(Grid::getCode,Grid::getParentCode,Grid::getName).ne(Grid::getLevel,"5");
//        List<String> fourGrid = Arrays.asList("SD.LA","SD.LB","SD.LA.0g","SD.LA.0d","SD.LA.0c","SD.LA.0b","531.0012.101", "531.0013.c03", "531.0014.d02", "531.0016.0010");
        List<String> fourGrid = Arrays.asList("SD.LB");
        List<String> qdDistrict = Arrays.asList("SD.LB.0b","SD.LB.0a","SD.LB.0d","SD.LB.0f");
        List<Grid> gridList = this.list(queryWrapper);
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("value");                              //默认id，可以不设置
        config.setParentIdKey("parentCode");                       //父id
        config.setNameKey("label");              //分类名称
        config.setChildrenKey("children");              //孩子节点
        config.setWeightKey("value");                     //排序字段
        //3.转树
        List<Tree<String>> list = TreeUtil.build(gridList, "0", config, ((object, treeNode) -> {
            treeNode.putExtra("value", object.getCode());
            treeNode.putExtra("parentCode", object.getParentCode());
            treeNode.putExtra("label", object.getName());
            if(fourGrid.contains(object.getCode()) || qdDistrict.contains(object.getCode()) || qdDistrict.contains(object.getParentCode())){
                treeNode.putExtra("isClick", true);
            }else{
                treeNode.putExtra("isClick", false);
            }
        }));
        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;
        log.info("解析数据执行时间：{}毫秒", executionTime);
        return list;
    }

    @Override
    public String getWktByCode(String code) {
        QueryWrapper<Grid> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(Grid::getWkt).eq(Grid::getCode,code);
        Grid grid = getOne(queryWrapper, false);
        if(Objects.isNull(grid)){
            throw new CommonException("获取边界数据失败");
        }
        return grid.getWkt();
    }
}
